import NodeRSA from 'node-rsa';
import Cookie from 'thinkjs/lib/util/cookie'

function transPw(pw, {
    mobile,
    signInfo
}) {
    // var salt = C('salt') || md5('integralmall');
    // return md5(md5(md5(pw) + salt) + md5(info));
    if (signInfo.key) {
        const key = new NodeRSA(signInfo.key.privateKey);
        pw = key.decrypt(pw, 'utf8');

    } else {
        throw new Error('signInfo.key is not exist.');
    }
    return think.md5(pw);
}

export default class extends think.controller.base {
    async indexAction() {
        let data = this.post();
        think.log('data is'+JSON.stringify(data), 'LOG');
        let cmd = data.cmd;
        think.log('api cmd: ' + cmd, 'LOG');

        // try {
        //     console.log(123123);
        //     await this.transData(data);
        // } catch (err) {
        //     console.log(err);
        //     if (think.isPrevent(err)) {
        //         return;
        //     }
        //
        //     const {
        //         errno = 1000, errmsg = '', errInfo = 'ERROR'
        //     } = err;
        //     think.log(err, errInfo);
        //     return this.fail(errno, errmsg);
        // }

        let resData;

        try {
            switch (cmd) {
                case 'signIn':
                    {
                        resData = await this.signIn(data);
                        think.log('in signin')
                        break;
                    }
                case 'signOut':
                    {
                        resData = await this.signOut(data);
                        break;
                    }
                case 'getUserInfo':
                    {
                        if (!data.token) {
                            const {
                                mobile
                            } = await this.session('userInfo') || {};
                            resData = await this.getUserInfo({
                                params: {
                                    mobile
                                }
                            });
                            await this.session('userInfo', resData);
                        } else {
                            resData = await this.getUserInfo(data);
                        }
                        break;
                    }
                case 'getPubKey':
                    {
                        resData = await this.getPubKey();
                        break;
                    }
                default:
                    resData = await this.transWithLogin(data);

            }
        } catch (err) {

            const {
                errno = 1000, errmsg = '', info, errInfo = 'ERROR'
            } = err;
            think.log(err, errInfo);
            return this.fail(errno, errmsg, info);
        }

        return this.success(resData);
    }

    async transData(data) {
        // data.version = '3.0.0';

        if (!think.isObject(data.params)) {
            data.params = {};
        }
        const signInfo = await this.session('signInfo') || {};
        // transCmd(data);
        // addAppCode(data.params, data.cmd);

        try {
            data.params.userPass && (data.params.userPass = transPw(data.params.userPass, {
                mobile: data.params.mobile,
                signInfo
            }));
            data.params.newPassword && (data.params.newPassword = transPw(data.params.newPassword, {
                mobile: data.params.mobile,
                signInfo
            }));
        } catch (e) {
            throw {
                errmsg: '密码解析出错',
                errno: 401,
                info: {
                    msg: e.message,
                    ...data.params
                }
            };
        }
    }
    async signIn(data) {
            const signInfo = await this.session('signInfo');
            if(JSON.stringify(signInfo) !== "{}"){
                return signInfo

            }else{
                console.log(JSON.stringify(data))
                var tran=this.getTranspond();
                const userInfo = await tran.send(data);
                await this.session('userInfo', userInfo);
                think.log(userInfo, 'LOG');
                return userInfo
            }

            // if (this.checkVerifycode && signInfo.signFailCount >= 3 && signInfo.validate != data.verifycode) {
            //     think.log('验证码错误', 'LOG');
            //     throw new Error('验证码错误');
            // } else {
            //     try {
            //         const {
            //             mobile
            //         } = await this.doAuth(data, signInfo);
            //
            //         think.log('signInfo: ' + JSON.stringify(signInfo), 'LOG');
            //         await this.session('signInfo', signInfo);
            //
            //         const userInfo = await this.getUserInfo({
            //             params: {
            //                 mobile
            //             }
            //         });
            //         await this.session('userInfo', userInfo);
            //
            //         return userInfo;
            //     } catch (err) {
            //         think.log('errno: ' + err.errno, 'LOG');
            //         if (this.checkVerifycode && err.errno) {
            //             signInfo.signFailCount = (signInfo.signFailCount | 0) + 1;
            //
            //             think.log('signInfo: ' + JSON.stringify(signInfo), 'LOG');
            //
            //             await this.session('signInfo', signInfo);
            //             err.info = err.info || {};
            //             err.info.signFailCount = signInfo.signFailCount;
            //             err.errno = parseInt('400' + err.errno.toString().substr(3));
            //         }
            //         throw err;
            //     }
            // }
        }
        // need overwrite
    async doAuth({
            auth,
            ...data
        }, signInfo) {
            /* const trans2Rs = this.getTranspond();

            const {
            	loginId,
            	password: token
            } = data;
            auth = auth || `${loginId},${token}`;

            const resData = await trans2Rs.send({
            	method: 'get',
            	path: `/user/${encodeURI(loginId)}/menus`
            }, auth);

            const mobile = resData.mobile;

            signInfo.token = auth;
            // signInfo.signFailCount = 0;

            return {
            	mobile
            };*/
            return {};
        }
        // need overwrite
    async getUserInfo({
        params: {
            mobile
        }
    }) {
        /*const {
        	dataList
        } = await this.transWithLogin({
        	method: 'get',
        	path: `/user/${mobile}/vehicles`
        });

        return {
        	mobile,
        	vehicleList: dataList || []
        };*/
        return {};
    }
    async getPubKey() {
        const signInfo = await this.session('signInfo') || {};
        if (!signInfo.key) {

            const key = new NodeRSA();
            key.generateKeyPair(1024);

            const privateKey = key.exportKey('pkcs1-private-pem');
            const publicKey = key.exportKey('pkcs1-public-pem');
            const publicPem = publicKey.replace('-----BEGIN RSA PUBLIC KEY-----', '')
                .replace('-----END RSA PUBLIC KEY-----', '')
                .replace(/\s+|\n\r|\n|\r$/gm, '');

            // console.log('key\n', privateKey, '\n', publicKey);

            signInfo.key = {
                privateKey,
                publicPem
            };

            // think.log('signInfo: ' + JSON.stringify(signInfo), 'LOG');

            await this.session('signInfo', signInfo);
        }

        return signInfo.key.publicPem;
    }
    async signOut(data) {
        this.useToken4Session(data);
        const {
            key
        } = await this.session('signInfo') || {};
        await this.session();
        await this.session('signInfo', {
            key
        });
    }
    async transWithLogin({
        token,
        ...data
    }) {
        this.useToken4Session({
            token
        });
        console.log(4678687687);
        const {
            token: auth
        } = await this.session('signInfo') || {};

        // begin 若后端响应状态码正确，后续可以考虑去掉该段逻辑
        const needLogin = this.needLogin(data);

        think.log(`transLoginInfo: needLogin:${needLogin} auth:${auth}`, 'LOG');
        // if (needLogin && !auth) {
        //     throw {
        //         errmsg: '未登录或登录过期',
        //         errno: 401
        //     };
        // }
        // end

        const transpond = this.getTranspond();
        console.log(768678);
        return transpond.send(data, auth);
    }
    async trans(data, auth) {
        const transpond2Java = this.getTranspond();

        return transpond2Java.send({
                headers: this.http.req.headers,
                ...data
            }, auth, true)
            .then(rawRes => {
                this.http.res.writeHead(rawRes.statusCode, rawRes.headers);
                rawRes.pipe(this.http.res);
            }).catch(e => {
                return this.error(500);
            })
    }
    useToken4Session({
        token
    }) {
        if (token) {
            if (this.http._session) {
                throw new Error('set token fail');
            }

            const sessionOptions = think.config('session');
            const {
                name,
                secret
            } = sessionOptions;

            const cookie = this.cookie(name);

            if (cookie !== token) {
                this.http._cookie[name] = token;
                think.log('use token: ' + token, 'LOG');

                // 不一致时回写cookie
                this.cookie(name, token);
            } else {
                think.log('use cookie: ' + cookie, 'LOG');
            }
        }
    }
    getSessionToken() {
        // console.log(this.http._sendCookie, this.http._cookie, this.http._session, this.http.headers.cookie);
        // delete this.http._cookie[name];
        // delete this.http.headers.cookie;

        think.session(this.http);

        const name = this.config('session').name;
        const Cookie = think.require('thinkjs/lib/util/cookie');

        let token = Cookie.parse(this.http.headers.cookie)[name];
        token = this.http._sendCookie[name] ? this.http._sendCookie[name].value : token;

        return token;
    }
    needLogin(data) {
        return true;
    }
    getTranspond(transpondConf = think.config('transpond')) {
        const Transpond = think.service('transpond');
        const transpond = new Transpond(transpondConf);

        return transpond;
    }
};